/**
 * project: finance-manage
 * package: com.example.models
 * 基于 Map 实现的 适用于本项目的 Json 模型
 * ！不具备完整的类型检查功能， 请保证类型正确
 * 目前支持的除基本数据类型意外的值类型: [数组] | {Json对象} | List对象
 * 是否支持嵌套： 支持
 */

package com.example.models;

import java.util.*;
import java.util.Map.Entry;

import com.example.interfaces.JsonModelInterface;
// import com.example.util.Debug;

public class JsonModel implements JsonModelInterface {

    private final HashMap<String, Object> dict;

    public JsonModel() {
        dict = new HashMap<>();
    }

    public JsonModel(BillDataModel bill) {
    this();
    dict.put("bid", bill.getBid());
    dict.put("type", bill.getType());
    dict.put("amount", bill.getAmount());
    dict.put("date", bill.getDate());
    dict.put("statement", bill.getStatement());
    dict.put("notes", bill.getNotes());
    }

    public JsonModel(String jsonstr) {
        this();
        /* 解析 jsonstr 并填充 dict */
        /* 去除首尾的花括号与空白字符 */
        jsonstr = jsonstr.trim().substring(1, jsonstr.length() - 1).trim();
        if (jsonstr.isEmpty()) {
            return;
        }
        /* 按逗号分割键值对 */
        String[] key_value_pairs = jsonstr.split(",");
        /* 定义下标，便于遍历时处理特殊情况 */
        int index = 0;
        /* 遍历键值对 */
        while (index < key_value_pairs.length) {
            /* 按冒号分割键值对 */
            String[] key_value = key_value_pairs[index].split(":", 2);
            /* 解析键 */
            String key = key_value[0].trim();
            /* 去除首尾的双引号 */
            key = key.substring(1, key.length() - 1);
            /* 清洗值 */
            String tmp_value = key_value[1].trim();
            /* 判断是否为对象或数组 */
            if (tmp_value.startsWith("{") || tmp_value.startsWith("[")) {
                char endChar = (char) (tmp_value.charAt(0) + 2);
                /* 判断对象或数组是否结束 */
                while (!tmp_value.endsWith(String.valueOf(endChar))) {
                    /* 将对象或数组重新拼接 */
                    index++;
                    tmp_value += "," + key_value_pairs[index].trim();
                }
            }

            /* 解析值 */
            Object value = parseValue(tmp_value);
            /* 填充字典 */
            dict.put(key, value);

            index++;
        }

    }

    private Object parseValue(String value) {
        /* 解析字符串值 */
        if (value.startsWith("\"")) {
            return value.substring(1, value.length() - 1);
        }
        /* 解析布尔值 */
        else if (value.equals("true")) {
            return true;
        } else if (value.equals("false")) {
            return false;
        }
        /* 解析null值 */
        else if (value.equals("null")) {
            return null;
        }
        /* 解析整型数值 */
        else if (value.matches("\\d+")) {
            return Integer.parseInt(value);
        }
        /* 解析小数数值 */
        else if (value.matches("\\d+\\.\\d+")) {
            return Double.parseDouble(value);
        }
        /* 对象 */
        else if (value.startsWith("{")) {
            /* 解析对象 */
            return new JsonModel(value);
        }
        /* 数组 */
        else if (value.startsWith("[")) {
            /* 去除首尾的方括号 */
            value = value.substring(1, value.length() - 1);
            /* 按逗号分割数组元素 */
            String[] items = value.split(",");
            /* 解析数组元素 */
            Object[] parsedItems = new Object[items.length];
            for (int i = 0; i < items.length; i++) {
                /* 可能损失性能，但简单有效 */
                parsedItems[i] = parseValue(items[i].trim());
            }
            return parsedItems;
        }
        /* 类型不适配 */
        else {
            return -1;
        }
    }

    @Override
    public String toString() {
        /* 定义一个字符串用于拼接 json 格式 */
        String jsonStr = "{";

        /* 使用迭代器遍历 Map 集合 */
        Set<Map.Entry<String, Object>> entrySet = this.dict.entrySet();
        Iterator<Map.Entry<String, Object>> iterator = entrySet.iterator();
        while (iterator.hasNext()) {
            Entry<String, Object> entry = iterator.next();
            /* 拼接键 */
            jsonStr += "\"" + entry.getKey() + "\":";
            /* 格式化值 */
            String value = formatValue(entry.getValue());
            /* 拼接值 */
            jsonStr += value;
            /* 追加逗号 */
            if (iterator.hasNext()) {
                jsonStr += ",";

            }
        }
        jsonStr += "}";

//        Debug.print(jsonStr);
        return jsonStr;
    }

    private String formatValue(Object value) {
        String jsonValueStr = "";
        if (value == null) {
            jsonValueStr += "null";
        }
        /* 处理数组 */
        else if (value instanceof Object[]) {
            jsonValueStr += "[";
            for (Object item : (Object[]) value) {
                jsonValueStr += formatValue(item) + ",";
            }
            if (jsonValueStr.endsWith(",")) {
                jsonValueStr = jsonValueStr.substring(0, jsonValueStr.length()-1);
            }
            jsonValueStr += "]";
        }
        // 处理 List 对象
        else if (value instanceof List) {
            jsonValueStr += "[";
            for (Object item : (List<?>) value) {
                jsonValueStr += formatValue(item) + ",";
            }
            if (jsonValueStr.endsWith(",")) {
                jsonValueStr = jsonValueStr.substring(0, jsonValueStr.length() - 1);
            }
            jsonValueStr += "]";
        } else if (value instanceof String) {
            jsonValueStr += "\"" + value + "\"";
        } else {
            jsonValueStr += value.toString();
        }
        return jsonValueStr;
    }

    @Override
    public Object get(String key) {
        return dict.get(key);
    }

    @Override
    public void push(String key, Object value) {
        dict.put(key, value);
    }

    @Override
    public void remove(String key) {
        dict.remove(key);
    }

}
